package gov.moandor.schultegrid;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity implements NumberButton.OnNumberClickListener {
	private NumberButton[] mBtns = new NumberButton[25];
	private TextView mTimer;
	private Button mStart;
	private int mCurrNum;
	private long mStartTime;
	private Handler mMainHandler;
	private Handler mBackgroundHandler;
	private String mTimerText;
	private boolean mStopped = true;
	private ScheduledExecutorService mScheduledExecutorService;
	private View mRoot;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mScheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
		mMainHandler = new Handler();
		mBackgroundThread.start();
		mRoot = findViewById(R.id.main);
		LinearLayout grid = (LinearLayout) findViewById(R.id.grid);
		mStart = (Button) findViewById(R.id.button_start);
		mTimer = (TextView) findViewById(R.id.timer);
		int i = 0;
		for (int i1 = 0; i1 < 5; i1++) {
			LinearLayout layout = new LinearLayout(this);
			layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 
					ViewGroup.LayoutParams.WRAP_CONTENT));
			for (int i2 = 0; i2 < 5; i2++) {
				mBtns[i] = (NumberButton) getLayoutInflater().inflate(R.layout.my_button, layout, false);
				mBtns[i].setOnNumberClickListener(this);
				layout.addView(mBtns[i]);
				mBtns[i].setEnabled(false);
				i++;
			}
			grid.addView(layout);
		}
		mStart.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mStopped) {
					start();
				} else {
					stop(true);
				}
			}
		});
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		if (!mStopped) {
			stop(true);
		}
	}
	
	private void stop(boolean resetTimer) {
		mStopped = true;
		for (Button btn : mBtns) {
			btn.setEnabled(false);
			btn.setText(null);
		}
		if (resetTimer) {
			mTimer.setText(R.string.timer_zero);
		}
		mStart.setText(R.string.start);
	}
	
	private void start() {
		mCurrNum = 0;
		List<Integer> list = randomIntList();
		for (int i = 0; i < 25; i++) {
			mBtns[i].setEnabled(true);
			mBtns[i].setNum(list.get(i));
		}
		mStopped = false;
		mStart.setText(R.string.stop);
		mStartTime = SystemClock.uptimeMillis();
		mBackgroundHandler.post(mTimerBackgroundRunnable);
	}
	
	private void blink() {
		mScheduledExecutorService.execute(new Runnable() {
			@Override
			public void run() {
				mMainHandler.post(new Runnable() {
					@Override
					public void run() {
						mRoot.setBackgroundResource(R.color.red);
					}
				});
			}
		});
		mScheduledExecutorService.schedule(new Runnable() {
			@Override
			public void run() {
				mMainHandler.post(new Runnable() {
					@Override
					public void run() {
						mRoot.setBackgroundResource(R.color.black);
					}
				});
			}
		}, 100, TimeUnit.MILLISECONDS);
	}
	
	private static List<Integer> randomIntList() {
		Random random = new Random();
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 1; i < 26; i++) {
			list.add(random.nextInt(list.size() + 1), i);
		}
		return list;
	}
	
	private Thread mBackgroundThread = new Thread() {
		@Override
		public void run(){
			Looper.prepare();
			mBackgroundHandler = new Handler();
			Looper.loop();
		}
	};
	
	private Runnable mTimerBackgroundRunnable = new Runnable() {
		private static final int MINUTE = 60 * 1000;
		
		@Override
		public void run(){
			if (!mStopped) {
				long interval = SystemClock.uptimeMillis() - mStartTime;
				int minutes = (int) interval / MINUTE;
				interval -= minutes * MINUTE;
				float second = interval / 1000f;
				mTimerText = String.format("%d:%06.3f", minutes, second);
				mMainHandler.post(mTimerUIRunnable);
			}
		}
	};
	
	private Runnable mTimerUIRunnable = new Runnable() {
		@Override
		public void run() {
			if (!mStopped) {
				mTimer.setText(mTimerText);
				mBackgroundHandler.post(mTimerBackgroundRunnable);
			}
		}
	};
	
	@Override
	public void onNumberClick(int num) {
		if (num == mCurrNum + 1) {
			if (num == 25) {
				stop(false);
			}
			mCurrNum = num;
		} else {
			blink();
		}
	}
}
